package com.own.demo;

import org.junit.jupiter.api.Test;
import org.openjdk.jol.info.ClassLayout;

/**
 * https://www.cnblogs.com/rickiyang/p/14206724.html
 *
 * @Author zyf
 * @Date 2025-06-03 16:24
 * Description:
 * @Version 1.0
 */
public class JMMDemo {

    /**
     * 在 Hotspot VM 中，对象在内存中的存储布局分为 3 块区域：
     * 对象头（Header） :MarkWord、元数据指针、数组长度
     * MarkWord：用于存储对象运行时的数据，好比 HashCode、锁状态标志、GC分代年龄等。这部分在 64 位操作系统下占 8 字节，32 位操作系统下占 4 字节
     * 指针：对象指向它的类元数据的指针，虚拟机通过这个指针来确定这个对象是哪一个类的实例;在开启指针压缩的状况下占 4 字节，未开启状况下占 8 字节
     * 要启用 oop 压缩，我们可以使用标志 -XX：+UseCompressedOops 进行调整，只要最大堆大小小于 32 GB。当最大堆大小超过32 GB时，JVM将自动关闭 oop 压缩
     * 数组长度：这部分只有是数组对象才有，若是是非数组对象就没这部分。这部分占 4 字节
     * 实例数据（Instance Data）
     * 实例数据就不用说了，用于存储对象中的各类类型的字段信息（包括从父类继承来的）
     * 对齐填充（Padding）
     * Java 对象的大小默认是按照 8 字节对齐，也就是说 Java 对象的大小必须是 8 字节的倍数。若是算到最后不够 8 字节的话，那么就会进行对齐填充。
     * 由于 CPU 进行内存访问时，一次寻址的指针大小是 8 字节，正好也是 L1 缓存行的大小。如果不进行内存对齐，则可能出现跨缓存行的情况，这叫做 缓存行污染。
     */

    @Test
    public void test() {
//        12（压缩指针+markWord）+4(int) + 4（String） + 4(对齐填充)
        ClassLayout classLayout = ClassLayout.parseInstance(new A());
        System.out.println(classLayout.toPrintable());
    }

    class A {
        //        4个字节
        int a = 10;
//        4 哥字节
        String c;
//        int[] d=new int[10];
    }
    class B{

    }


}
